﻿using System;
using Moq;
using NUnit.Framework;

namespace TimeBoardTest
{
    /// <summary>
    /// The unit tests for <see cref="TimeBoard"/> implementation.
    /// </summary>
    [TestFixture]
    public class TimeBoardTest
    {
        private MockRepository mockRepository;

        /// <summary>
        /// Sets up the test method.
        /// </summary>
        [SetUp]
        public void SetUp()
        {
            this.mockRepository = new MockRepository(MockBehavior.Default);
        }

        /// <summary>
        /// Tears down the test method.
        /// </summary>
        [Test]
        public void TearDown()
        {
            this.mockRepository = null;
        }

        #region Helper Methods

        /// <summary>
        /// Creates the match timer mock.
        /// </summary>
        /// <returns></returns>
        private Mock<IPlayTimer> CreateMatchTimerMock()
        {
            return this.mockRepository.Create<IPlayTimer>();
        }

        #endregion

        /// <summary>
        /// Tested API: Constructor
        /// Test Scenario: playTimer is not null.
        /// Expected Behavior: playTimer is set with same instance.
        /// </summary>
        [Test]
        public void Constructor_MatchTimerNotNull_IsSet()
        {
            // test preparation
            IPlayTimer playTimer = CreateMatchTimerMock().Object;
            // test execution
            ITimeBoard timeBoard = new TimeBoard(playTimer);
            // test verification
            Assert.AreEqual(playTimer, timeBoard.PlayTimer,
                "playTimer is not set as same instance as given in constructor.");
        }

        /// <summary>
        /// Test API: Constructor
        /// Test Scenario: MatchTimerParamIsNull
        /// Expected Behavior: ArgumentNullException
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void Constructor_MatchTimerParamIsNull_ArgumentNullException()
        {
            // test preparation
            IPlayTimer playTimer = null;
            // test execution
            new TimeBoard(playTimer);
        }
    }

    /// <summary>
    /// The TimeBoard interface.
    /// Provides following functionality:
    /// Gets the match timer.
    /// </summary>
    public interface ITimeBoard
    {
        /// <summary>
        /// Gets the match timer.
        /// </summary>
        /// <value>
        /// The match timer.
        /// </value>
        IPlayTimer PlayTimer { get; }
    }

    /// <summary>
    /// The default implementation of <see cref="ITimeBoard"/> interface.
    /// </summary>
    public class TimeBoard : ITimeBoard
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeBoard" /> class.
        /// </summary>
        /// <param name="playTimerIn">The match timer.</param>
        public TimeBoard(IPlayTimer playTimerIn)
        {
            if (playTimerIn == null)
            {
                throw new ArgumentNullException("playTimerIn");
            }
            PlayTimer = playTimerIn;
        }

        /// <summary>
        /// Gets the match timer.
        /// </summary>
        /// <value>
        /// The match timer.
        /// </value>
        public IPlayTimer PlayTimer { get; private set; }
    }
}
